#include <buola/chart/plots/cbarplot.h>

#include <buola/image/cgc.h>
#include <buola/chart/cxychart.h>
#include <buola/chart/cxaxis.h>
#include <buola/chart/cyaxis.h>

namespace buola { namespace chart {

CBarPlot::CBarPlot()
    :   mBarColor(L"orangered")
    ,   mLineColor(L"black")
    ,   mBarWidth(1)
{
}

CBarPlot::~CBarPlot()
{
}

///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
////////////////////////// Interface //////////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////

void CBarPlot::AddSeries(PSeries pSeries)
{
    if(mSeries.empty())
    {
        if(pSeries->size()>1)
            mBarWidth=min(diff(pSeries->mXData));
    }
    
    mSeries.push_back(pSeries);
}

void CBarPlot::SetBarColor(const img::CColor &pColor)
{
    mBarColor=pColor;
}

void CBarPlot::SetLineColor(const img::CColor &pColor)
{
    mLineColor=pColor;
}

double CBarPlot::GetMinX()
{
    if(mSeries.empty()||!mSeries[0]->size()) return 0;
    
    return mSeries[0]->mXData(0)-mBarWidth/2;
}

double CBarPlot::GetMaxX()
{
    if(mSeries.empty()||!mSeries[0]->size()) return 0;
    
    return mSeries[0]->mXData(mSeries[0]->size()-1)+mBarWidth/2;
}

double CBarPlot::GetMinY()
{
    double lMin=0.0;

    for(int i=0;i<mSeries.size();i++)
    {
        lMin=min(lMin,mSeries[i]->mMin.y);
    }
    
    return lMin;
}

double CBarPlot::GetMinPosY()
{
    double lMin=INFINITY;

    for(int i=0;i<mSeries.size();i++)
    {
        lMin=min(lMin,mSeries[i]->mMinPos.y);
    }
    
    return lMin;
}

double CBarPlot::GetMaxY()
{
    double lMax=0.0;

    for(int i=0;i<mSeries.size();i++)
    {
        lMax=max(lMax,mSeries[i]->mMax.y);
    }
    
    return lMax;
}

void CBarPlot::Draw(CXYChartContext &pC)
{
    if(mSeries.empty()) return;


    for(int i=0;i<mSeries.size();i++)
    {
        pC.mGC->SetLineWidth(1.0);
        for(int j=0;j<mSeries[i]->size();j++)
        {
            CRect_d lRect(pC.mXAxis->Map(mSeries[i]->GetX(j)-0.4*mBarWidth),pC.mYAxis->Map(0),
                          pC.mXAxis->Map(mSeries[i]->GetX(j)+0.4*mBarWidth),pC.mYAxis->Map(mSeries[i]->GetY(j)));
            lRect.Normalize();
            pC.mGC->Path().Rect(lRect.TopLeft(),lRect.Size());
            if(mSeries[i]->mColor.Valid())
                pC.mGC->SetSource(mSeries[i]->mColor);
            else
                pC.mGC->SetSource(mBarColor);
            
            pC.mGC->FillPath(true);
            pC.mGC->SetSource(mLineColor);
            pC.mGC->StrokePath();
        }
    }
}

//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
/////////////////////// internals ////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////


/*namespace chart*/ } /*namespace buola*/ }
